package com.cg.conf.exception;//
//package com.cg.conf.exception;
//
//import com.cg.conf.exception.annotation.GlobalException;
//import com.cg.conf.exception.exception.GlobalExceptionProcess;
//import com.cg.conf.exception.exception.IGlobalException;
//import lombok.extern.slf4j.Slf4j;
//import org.hibernate.validator.internal.util.ConcurrentReferenceHashMap;
//import org.reflections.Reflections;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.core.ExceptionDepthComparator;
//import org.springframework.web.bind.annotation.ExceptionHandler;
//import org.springframework.web.bind.annotation.RestControllerAdvice;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.util.*;

/**
 * Global exception handling class
 *
 * @author shinetan
 * @since 0.1.0
 */
//
//@RestControllerAdvice
//@Slf4j
//public class GlobalExceptionHandler {
//
//    //扫描基础包
//    private final String scanBasePackage;
//
//    //排除的异常类
//    private final List<String> exclusionDefaultGlobalException;
//
//    private final Map<Class<? extends Throwable>, IGlobalException> mappedExceptions = new HashMap<>(16);
//
//    private final Map<Class<? extends Throwable>, IGlobalException> exceptionLookupCache = new ConcurrentReferenceHashMap<>(16);
//
//    public GlobalExceptionHandler(@Value("${global.exception.exclusionDefaultGlobalException:}") List<String> exclusionDefaultGlobalException, @Value("${global.exception.scanBasePackage:}") String scanBasePackage) {
//        this.scanBasePackage = scanBasePackage;
//        this.exclusionDefaultGlobalException = exclusionDefaultGlobalException;
//        init();
//    }


//    @ExceptionHandler(LoginValidationException.class)
//    public ResponseEntity<Map<String, Object>> handleLoginValidationException(LoginValidationException ex, HttpServletRequest request) {
//        Map<String, Object> responseBody = new HashMap<>();
//        responseBody.put("success", false);
//        responseBody.put("code", 100501); // 定义一个特定的错误码
//        responseBody.put("message", ex.getMessage()); // 使用异常中的消息
//        return new ResponseEntity<>(responseBody, HttpStatus.BAD_REQUEST);
//    }
//    private void init() {
//        Reflections reflections = new Reflections(scanBasePackage);
//        Set<Class<?>> classes = reflections.getTypesAnnotatedWith(GlobalException.class);
//        for (Class<?> clazz : classes) {
//            if (verifyClassCanBeAdded(clazz)) {
//                continue;
//            }
//            addClassToMappedExceptions(clazz);
//        }
//        IGlobalException iGlobalException = mappedExceptions.get(Throwable.class);
//        if (iGlobalException == null) {
//            mappedExceptions.put(Exception.class, new GlobalExceptionProcess());
//        }
//    }


/**
     * Add class to mappedExceptions.
     * If duplicate throwable exists during saving, which needs to be overwritten according to priority.
     *
     * @param clazz Class<? extends Throwable>
     */

//    private void addClassToMappedExceptions(Class<?> clazz) {
//        GlobalException currentAnno = clazz.getAnnotation(GlobalException.class);
//        Class<? extends Throwable> throwable = currentAnno.throwable();
//        IGlobalException sourceException = mappedExceptions.get(throwable);
//        try {
//            if (sourceException == null) {
//                mappedExceptions.put(throwable, (IGlobalException) clazz.newInstance());
//                return;
//            }
//            GlobalException sourceAnno = sourceException.getClass().getAnnotation(GlobalException.class);
//            if (currentAnno.priority() < sourceAnno.priority()) {
//                log.warn("The exception already exists, overwrite the original exception! exception type: {}", throwable);
//                log.warn("Original exception info：{}, class name: {}", sourceAnno, sourceException.getClass().getName());
//                log.warn("Current exception info：{}, class name: {}", currentAnno, clazz.getName());
//                mappedExceptions.put(throwable, (IGlobalException) clazz.newInstance());
//            } else {
//                log.warn("The exception already exists and has a low priority. The original exception cannot be overwritten! exception type: {}", throwable);
//                log.warn("Original exception info：{}, class name: {}", sourceAnno, sourceException.getClass().getName());
//                log.warn("Current exception info：{}, class name: {}", currentAnno, clazz.getName());
//            }
//        } catch (Exception e) {
//            log.error("", e);
//        }
//    }
//
//    private boolean verifyClassCanBeAdded(Class<?> clazz) {
//        if (!checkAssignableFrom(IGlobalException.class, clazz.getInterfaces())) {
//            log.error("The IGlobalException interface is not implemented and cannot be added to mappedExceptions, class name: {}", clazz.getName());
//            return true;
//        }
//        if (isExclusionDefaultGlobalException(clazz.getName())) {
//            log.warn("Global exception handler{" + clazz.getName() + "} In the exclusion list, do not add.");
//            return true;
//        }
//        return false;
//    }
//
//    private boolean checkAssignableFrom(Class<?> assignableClass, Class<?>... classes) {
//        for (Class face : classes) {
//            if (face.isAssignableFrom(assignableClass)) {
//                return true;
//            }
//        }
//        return false;
//    }
//
//    public IGlobalException getCacheException(Class<? extends Throwable> exceptionType) {
//        IGlobalException globalException = this.exceptionLookupCache.get(exceptionType);
//        if (globalException == null) {
//            globalException = getMappedException(exceptionType);
//            this.exceptionLookupCache.put(exceptionType, globalException);
//        }
//        return globalException;
//    }
//
//    private IGlobalException getMappedException(Class<? extends Throwable> exceptionType) {
//        List<Class<? extends Throwable>> matches = new ArrayList<>();
//        for (Class<? extends Throwable> mappedException : this.mappedExceptions.keySet()) {
//            if (checkAssignableFrom(exceptionType, mappedException)) {
//                matches.add(mappedException);
//            }
//        }
//        if (!matches.isEmpty()) {
//            if (matches.size() > 1) {
//                matches.sort(new ExceptionDepthComparator(exceptionType));
//            }
//            return this.mappedExceptions.get(matches.get(0));
//        }
//        return null;
//    }
//
//    private boolean isExclusionDefaultGlobalException(String className) {
//        if (exclusionDefaultGlobalException == null || exclusionDefaultGlobalException.isEmpty()) {
//            return false;
//        }
//        for (String exclusionClassName : exclusionDefaultGlobalException) {
//            if (exclusionClassName.equals(className)) {
//                return true;
//            }
//        }
//        return false;
//    }
//
//    @ExceptionHandler(value = Throwable.class)
//    public Object exceptionHandler(Throwable throwable, HttpServletRequest request, HttpServletResponse response) {
//        IGlobalException iGlobalException = getCacheException(throwable.getClass());
//        return iGlobalException.exception(throwable, request, response);
//    }
//
//}
//
